package com.tsystems.clientEmployee.gui;

import java.awt.Component;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumnModel;

import com.tsystems.entities.Train;



public class TrainTable extends JTable {
	
	private static final long serialVersionUID = 161550993195410518L;
	private TrainsTableModel model;
	private ListSelectionListener listener;
	
	
	public TrainTable() {
		model = new TrainsTableModel();

		setModel(model);
		
		setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
			
			private static final long serialVersionUID = -4448416295222440127L;

			@Override
			public Component getTableCellRendererComponent(JTable table,
					Object value, boolean isSelected, boolean hasFocus,
					int row, int column) {
				super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				
				if (value != null) {
					this.setText(TrainsTableColumns.values()[column].format(value));
				}
				return this;
			}
		});
		
		TableColumnModel columnModel = getColumnModel();
	
		for (int i = 0; i < TrainsTableColumns.values().length; i++) {
			int width = TrainsTableColumns.values()[i].getWidth();
			columnModel.getColumn(i).setPreferredWidth(width);
		}
		
		getTableHeader().setReorderingAllowed(false);
		getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		getSelectionModel().addListSelectionListener(new ListSelectionListener() {		
			public void valueChanged(ListSelectionEvent e) {
				listener.valueChanged(e);
			}
		});
	}
	
	public Train getSelectedTrain() {
		int selectRow = getSelectedRow();
		return selectRow >= 0 ? model.getData(selectRow) : null;
	}
	
	public List<Train> getTrains() {
		return model.getCheckedMessages();
	}
	
	public TrainsTableModel getModel() {
		return model;
	}
	
	public void setSelectListener(ListSelectionListener listener) {
		this.listener = listener;
	}

	public void updateTable(List<Train> stations) {
		model.setData(stations);
	}
}

class TrainsTableModel extends AbstractTableModel {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -3213358527382430135L;
	private List<Train> data;
	private boolean[] select;
	
	public TrainsTableModel() {
		data = new ArrayList<Train>();
		select = new boolean[0];
	}

	public void setData(List<Train> data) {
		this.data = data;
		select = new boolean[data.size()];
		fireTableDataChanged();
	}
	
	public Train getData(int row) {
		return data.get(row);
	}
	
	public int getRowCount() {
		return data.size();
	}
	
	@Override
	public String getColumnName(int column) {
		return TrainsTableColumns.values()[column].getTitle();
	}

	public int getColumnCount() {
		return TrainsTableColumns.values().length;
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		TrainsTableColumns column = TrainsTableColumns.values()[columnIndex];
			return column.getValue(data.get(rowIndex));
	}
	
	@Override
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		if (columnIndex == 0) {
			select[rowIndex] = (Boolean) aValue;
		}
	}
	
	@Override
	public Class<?> getColumnClass(int columnIndex) {
		return TrainsTableColumns.values()[columnIndex].getColumnClass();
	}
	
	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return TrainsTableColumns.values()[columnIndex].isCellEditable();
	}
	
	public List<Train> getCheckedMessages() {
		List<Train> result = new ArrayList<Train>();

		for (int i = 0; i < select.length; i++) {
			if (select[i]) {
				result.add(data.get(i));
			}		
		}
		
		return result;
	}
	
	
}

enum TrainsTableColumns {

    NUMBER(" № поезда", 300) {
        @Override
        public Object getValue(Train m) {
            return m.getNumber();
        }
    },
    
    SEATS("Количество мест", 300) {
        @Override
        public Object getValue(Train m) {
            return m.getSeats();
        }
    };

    private final String title;
    private final int width;

    TrainsTableColumns(String title, int width) {
        this.title = title;
        this.width = width;
    }

    public String getTitle() {
        return title;
    }

    public int getWidth() {
        return width;
    }

    public String columnName() {
        return title;
    }

    public String format(Object arg0) {
        return arg0 == null ? "" : arg0.toString();
    }

    public Class<?> getColumnClass() {
        return String.class;
    }

   public boolean isCellEditable() {
        return false;
    }

    public abstract Object getValue(Train m);
}
